package com.ease.util {
   import com.ease.util.logging.LogManager;

   import flash.events.Event;
   import flash.events.IOErrorEvent;
   import flash.events.SecurityErrorEvent;
   import flash.net.FileReference;

   import mx.collections.ArrayCollection;
   import mx.logging.ILogger;

   /**
    * Utility file functions.
    */
   public class FileUtil {
      //Logger utility
      private static const _logger:ILogger = LogManager.getLogger(FileUtil);

      /** Keep a reference to already started download/upload processes. */
      private static const _fileReferences:Array/*FileReference*/ = [];

      /**
       * Returns a new instance of <code>FileReference</code> object. The object will be
       * monitored and reference to it will be kept until the download/upload process does
       * not finish. Thus we will prevent the garbage collector to release the object when it
       * goes out of scope. According to the <code>FileRefrence</code> documentation
       * any incomplete upload or download would be canceled when the <code>FileRefrence</code>
       * object goes out of scope.
       */
      public static function getFileReference():FileReference {
         var fileReference:FileReference = new FileReference();

         fileReference.addEventListener(IOErrorEvent.IO_ERROR,
            function onIOError(event:IOErrorEvent):void {
               onProcessFinished(fileReference);
            }
         );
         fileReference.addEventListener(SecurityErrorEvent.SECURITY_ERROR,
            function onSecurityError(event:Event):void {
               onProcessFinished(fileReference);
            }
         );
         fileReference.addEventListener(Event.COMPLETE,
            function onProcessComplete(event:Event):void {
               onProcessFinished(fileReference);
            }
         );
         fileReference.addEventListener(Event.SELECT,
            function onProcessBegin(e:Event):void {
               onProcessStarted(fileReference);
            }
         );

         return fileReference;
      }

      /**
       * Called when a download/upload process has begun
       */
      private static function onProcessStarted(fileReference:FileReference):void {
         _fileReferences.push(fileReference);
      }

      /**
       * Called when a download/upload process has finished
       */
      private static function onProcessFinished(fileReference:FileReference):void {
         var itemIndex:int = _fileReferences.indexOf(fileReference);
         if (itemIndex > -1) {
            _fileReferences.splice(itemIndex, 1);
         } else {
            _logger.warn("The process {0} has not been registered or has been already " +
               "unregistered", fileReference.toString());
         }
      }
   } //end of class
} //end of package